from enum import Enum
from typing import Union, Dict

from pydantic import validator, Field, BaseModel, EmailStr
from bson import ObjectId
from exceptions import InvalidParam
from ioservice import const
from models.alumni.alumni_institution import *
from models.alumni.alumni_reward import *
from schemas.search import QuerySearchParam


class ValidateAlumniFieldModel(BaseModel):
    name: Optional[str]
    identify_id: Optional[str]
    phone: Optional[str]
    email: Optional[Dict[str, List[str]]]


class AlumniInstitutionEnum(Enum):
    work = AlumniWorkModel  # 工作经历
    position = AlumniPositionModel  # 党校之友任职履历
    education = AlumniEducationModel  # 教育经历


class AlumniRewardEnum(Enum):
    award = AlumniAwardModel  # 获得奖项
    paper = AlumniPaperModel  # 编写著作
    journal_paper = AlumniJournalPaperModel  # 期刊论文
    conference_paper = AlumniConferencePaperModel  # 会议论文
    construction_project = AlumniConstructionProjectModel  # 参与工程项目
    academic_project = AlumniAcademicProjectModel  # 参与科研项目
    activity_patent = AlumniActivityPatentModel  # 活动专利
    standard = AlumniStandardModel  # 编制标准


class AlumniInfoEnum(Enum):
    # # TODO 临时方案,保存整体
    work = AlumniWorkModel  # 工作经历
    position = AlumniPositionModel  # 党校之友任职履历
    education = AlumniEducationModel  # 教育经历

    award = AlumniAwardModel  # 获得奖项
    paper = AlumniPaperModel  # 编写著作
    journal_paper = AlumniJournalPaperModel  # 期刊论文
    conference_paper = AlumniConferencePaperModel  # 会议论文
    construction_project = AlumniConstructionProjectModel  # 参与工程项目
    academic_project = AlumniAcademicProjectModel  # 参与科研项目
    activity_patent = AlumniActivityPatentModel  # 活动专利
    standard = AlumniStandardModel  # 编制标准


class AlumniExtraDataType(str, Enum):
    reward = "reward"
    institution = "institution"


class AlumniExtraDataModel(BaseModel):
    data_model: Optional[Union[str, AlumniInfoEnum]] = Field(title="校友信息类型")
    data_col: Optional[str] = Field(title="校友信息表")
    data: Optional[Union[dict, BaseModel]] = Field(title="校友字段信息")

    @validator("data_model")
    def parse_data_model(cls, v):
        if type(v) == str:
            try:
                return AlumniInfoEnum.__getattr__(v).value
            except Exception as e:
                raise InvalidParam("func", "不是正确的校友额外信息")
        return v

    def trans_data_model(self):
        if not self.data_model:
            raise InvalidParam("data_model", "data_model not settled")
        self.data = self.data_model(**self.data)
        return self.data

    def set_data_col(self):
        self.data_col = getattr(const, f"alumni_{AlumniInfoEnum(self.data_model).name}_col")
        return self.data_col


class AlumniExtraDataSearchModel(AlumniExtraDataModel):
    parameters: Optional[QuerySearchParam] = Field("搜索参数")
    person_id: Optional[List[OID]]
    reward_id: Optional[List[OID]]

    def compose_mongo_query(self):
        self.set_data_col()
        query = {"is_deleted": {"$ne": True}}
        if self.person_id:
            id_field = "person_ids" if self.check_info_type(AlumniExtraDataType.reward) else "person_id"
            query.update({id_field: {"$in": self.person_id}})
        if self.reward_id:
            query.update({"_id": {"$in": self.reward_id}})
        if self.parameters:
            query.update(self.parameters.load_mongo_query(self.data_model))
        return self.data_col, self.data_model, query

    def check_info_type(self, data_type: AlumniExtraDataType):
        if data_type == AlumniExtraDataType.reward:
            return self.data_model in [v.value for v in AlumniRewardEnum.__members__.values()]
        else:
            return self.data_model in [v.value for v in AlumniInstitutionEnum.__members__.values()]


if __name__ == '__main__':
    d = ValidateAlumniFieldModel(name='a', phone='d', identify_id='3', emails={"$in":["1","2"]})
    print(d.dict())